#include <muduo/net/EventLoop.h>
#include <muduo/net/TcpServer.h>
#include <muduo/net/TcpConnection.h>


#include <iostream>
#include <unordered_map>
#include <memory>
#include <functional>

class TranslaServer{
private:

    void ConnectionCallback(const muduo::net::TcpConnectionPtr& conn){
        if(!conn->connected())
        {
            std::cout << "新连接关闭" << std::endl;
        }
        else
        {
            std::cout << "新连接成功" << std::endl;
        }   

    }

    std::string Translate(std::string english){
        std::unordered_map<std::string,std::string> dict_map = {
            {"apple","苹果"},
            {"hello","你好"}
        };      
        // for(auto k : dict_map)
        //     std::cout << k.first << std::endl;

        std::cout <<"eglish:" << english << std::endl; 
        // english.resize(english.size() - strlen("\n"));//注意tcp协议中粘包问题的\r\n，需要把\r\n字符去除，才能算原本的字符串也才能正确的判断
        auto iter = dict_map.find(english);
        
        if(iter == dict_map.end())
        {
            return "查不到此单词\n";
        }

        return iter->second + "\n";
    } 
    
    void MessageCallback(const muduo::net::TcpConnectionPtr& conn,muduo::net::Buffer*buf,muduo::Timestamp time){
        //将请求的数据从buf中取出来
        std::string str = buf->retrieveAllAsString();
    
        //调用Translate接口进行翻译
        std::string chinese = Translate(str);

        //对客户端对象进行send发送响应
        conn->send(chinese);
     }


public:
    TranslaServer(int port):_server(&_baseloop,muduo::net::InetAddress("0.0.0.0",port),"TranslateServer",muduo::net::TcpServer::kReusePort)//kReusePort启动端口复用
    {
        auto func1 = std::bind(&TranslaServer::ConnectionCallback,this,std::placeholders::_1);
        
        //bind的使用：
        //将this指针提前给到函数ConnectionCallback的第一个参数，从后开始就第一个参数实际是原本的第二个参数！！！！


        _server.setConnectionCallback(func1);//调用有连接后所要执行的函数
        
        auto func2 = std::bind(&TranslaServer::MessageCallback,this,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3);
        //
        _server.setMessageCallback(func2);
    }

    void start()
    {
        _server.start();
        _baseloop.loop();
    }
private:
    muduo::net::EventLoop _baseloop;//放到前面，先进行构造，因为在初始化构造_server时要先使用baseloop
    muduo::net::TcpServer _server;
};


int main()
{
    TranslaServer svr(8081);
    svr.start();
    return 0;
}
